package com.hxzy.apsect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @author wzm
 * @create 2024-03-12 11:34
 * project_name:JavaWeb2401
 * @Description
 */
//2.编写AOP程序为指定的方法添加逻辑

//@Component //加入ioc容器
//@Aspect //标记当前类为切面类 才能给方法进行增强
@Slf4j
//@Order(1)  //改变切面类的执行顺序 （从类开数字越小预先执行 但是 从通知看 前置通知数字越小越先执行 后置通知数字越小越后执行）
public class TimeAspect {

    //抽取公共的切入点表达式
    @Pointcut("execution(* com.hxzy.service.*.*(..))")
    public void pt(){}



    //前置通知
//    @Before("execution(* com.hxzy.service.*.*(..))")
    @Before("pt()") //引用切入点表达式
    public void before(){
        log.info("前置通知...");
    }

    //环绕通知
    //用于给指定方法添加记录时间的代码
    //com.hxzy.service下任意类的任意方法的任意参数的方法可以被增强
//    @Around("execution(* com.hxzy.service.*.*(..))") //需要指定aop程序执行时给哪些方法增强 指定切入点表达式（哪个 哪些方法）
    @Around("pt()") //需要指定aop程序执行时给哪些方法增强 指定切入点表达式（哪个 哪些方法）
    public Object recordTime(ProceedingJoinPoint pjp) throws Throwable {
        //获取方法执行的开始时间
        long begin = System.currentTimeMillis();
        log.info("环绕前");

        //执行原始方法
        Object proceed = pjp.proceed(); //pjp为执行原始方法的对象保存和原始方法相关的信息 返回值为原始方法的返回值


        log.info("环绕后");
        //获取方法的结束时间
        long end = System.currentTimeMillis();

        //计算方法执行的耗时 getSignature()方法签名 理解为方法名
        log.info(pjp.getSignature()+"的执行耗费了{}毫秒的时间。",end-begin);


        return  proceed;//原始方法执行的返回
    }

    //后置通知
//    @After("execution(* com.hxzy.service.*.*(..))")
    @After("pt()")
    public void after(){
        log.info("后置通知...");
    }


    //返回后通知  异常不执行
//    @AfterReturning("execution(* com.hxzy.service.*.*(..))")
    @AfterReturning("pt()")
    public void afterTeturning(){
        log.info("返回后通知...");
    }

    //异常通知
//    @AfterThrowing("execution(* com.hxzy.service.*.*(..))")
    @AfterThrowing("pt()")
    public void afterThrowing(){
        log.info("异常通知...");
    }


}
